<?php
/**
 * @author Jean-Nicolas DESJARDINS
 * @copyright DDB Link
 * @name Ddb_User_Ldap
 * @version 1.0.0
 */
class Ddb_User_Ldap extends Jnd_User
{
    /**
     * Le serveur ldap par défaut
     *
     * @var string $_hostname
     */
    protected $_hostname = "net.lan";
    /**
     * Le port ldap par défaut
     *
     * @var int $_hostname
     */
    protected $_port = 389;
    /**
     * Le domaine ldap par défaut
     *
     * @var string $_domaine
     */
    protected $_domaine = "net";
    /**
     * Le type ldap par défaut
     *
     * @var string $_type
     */
    protected $_type = "ad";
    /**
     * La racine du db ldap par défaut
     *
     * @var string $_racineDn
     */
    protected $_racineDn = "cn=";
    /**
     * Le dn du serveur ldap par défaut
     *
     * @var string $_dn
     */
    protected $_dn = "DC=net,DC=lan";
    /**
     * L'utilisateur de consultation ldap par défaut
     *
     * @var string $_utilisateur
     */
    protected $_utilisateur = Jnd_Global_Constantes::Ddb_LDAP_USER_READER_DEFAULT;
    /**
     * Le mot de passe de consultation ldap par défaut
     *
     * @var string $_mdp
     */
    protected $_mdp = Jnd_Global_Constantes::Ddb_LDAP_USER_READER_DEFAULT_PASSWORD;
    /**
     * ON stock la connexion ldap
     *
     * @var Zend_Ldap $_ldap
     */
    protected $_ldap = null;
    /**
     * ON stock les données ldap
     *
     * @var Zend_Ldap $_donneesLdap
     */
    protected $_donneesLdap = null;
    /**
     * ON Paramètre les champs à remonter
     *
     * @var array $_remonter
     */
    // protected $_remonter = array(
    // 'cn',
    // 'displayname',
    // 'givenname',
    // 'sn',
    // 'company',
    // 'memberof',
    // 'mail',
    // 'telephonenumber',
    // 'displaynameprintable',
    // 'distinguishedName'
    // );
    protected $_remonter = array(
        '*'
    );

    /**
     *
     * @return string
     */
    public function __toString()
    {
        return (string) $this->recupAttributLdap("dn");
    }

    function __construct( $initval, array $config = null )
    {
        if ($config instanceof Zend_Config) {
            $config = $config->toArray();
        }
        if (isset($config['remonter'])) {
            $this->_retourner = $config['remonter'];
            $this->_remonter = $config['remonter'];
            unset($config['remonter']);
        }
        if (is_null($config)) {
            $config = Jnd_App::getConfig("ldap");
            if (! isset($config['host'])) {
                $config['host'] = $this->get_hostname();
                $config['port'] = $this->get_port();
                $config['baseDn'] = $this->get_dn();
                $config['username'] = $this->get_utilisateur();
                $config['password'] = base64_decode($this->get_mdp());
            }
        }
        
        $this->set_hostname($config['host']);
        $this->set_port($config['port']);
        $this->set_dn($config['baseDn']);
        $this->set_utilisateur($config['username']);
        $this->set_mdp($config['password']);
        
        $network = Jnd_App::getConfig('network');
        if (isset($network['disconnected']) && $network['disconnected']) {
            /*
             * Nécessaire que si l'on veut simuler le méthode "sauvegarder"
             * $fldap = APPLICATION_PATH . '/configs/comptes/connexion.ldap';
             * $this->_ldap = $this->chargeFichier($fldap);
             */
            $fldap = APPLICATION_PATH . '/configs/comptes/' . $network['identity'] . '.ldap';
            $utilisateurs = $this->chargeCompte($fldap);
        } else {
            $ldap = new Zend_Ldap($config);
            $ldap->bind();
            $this->_ldap = $ldap;
            $utilisateurs = $this->recuperationInfosLdap($initval);
            /*
             * Nécéssaire quand on veut sauvegarder un profil pour le travail
             * hors connexion $fldap = APPLICATION_PATH . '/configs/comptes/' .
             * $nomGoogle . '.ldap'; $this->sauveCompte($fldap, $utilisateurs);
             */
        }
        
        if (count($utilisateurs) == 1 && is_array($utilisateurs)) {
            /*
             * if (key_exists('objectguid', $utilisateurs[0])) {
             * $utilisateurs[0]['ldif'][0] =
             * Zend_Ldap_Ldif_Encoder::encode($utilisateurs[0]); } elseif
             * (key_exists('memberof', $utilisateurs[0])) {
             * $utilisateurs[0]['memberof'] =
             * $this->traitementGroupes($utilisateurs[0]['memberof']); }
             */
            $this->_donneesLdap = $utilisateurs[0];
        }
    
    }

    protected function traitementGroupes( $listeGroupes = null )
    {
        $tmpGroupes = array();
        if (is_array($listeGroupes)) {
            foreach ($listeGroupes as $groupe) {
                if (self::isAppGroup($groupe, 'CN=APP_')) {
                    $tmpGroupes[] = $groupe;
                }
            }
        }
        $listeGroupes = $tmpGroupes;
        return $listeGroupes;
    }

    public static function isAppGroup( $name, $head = 'APP_' )
    {
        return (substr($name, 0, strlen($head)) == $head);
    }

    /**
     *
     * @author Thierry BROUARD (BIIS)
     *        
     * @param $complet boolean
     *            version détaillé ou non des groupes
     * @return array $results nom des groupes
     */
    public function nomGroupes( $complet = false )
    {
        $results = array();
        if (isset($this->_donneesLdap['memberof'])) {
            if ($complet) {
                $results = $this->_donneesLdap['memberof'];
            } else {
                foreach ($this->_donneesLdap['memberof'] as $groupe) {
                    // @todo à remplacer par preg_match_all
                    $items = explode(',', $groupe);
                    $bloc = $items[0];
                    $grp = explode('=', $bloc);
                    $results[] = $grp[1];
                }
            }
        }
        return $results;
    }

    private function recuperationInfosLdap( $recherche )
    {
        $utilisateurs = '';
        $ldap = $this->_ldap;
        $recherche = trim($recherche);
        if (strpos($recherche, ',OU=') !== false) {
            if (strpos($recherche, ',DC=') === false) {
                $recherche .= ',' . $this->get_dn();
            }
            $searchField = "distinguishedName";
        } elseif (strpos($recherche, '/') !== false) {
            $recherche = strtolower(str_replace(" ", ".", substr($recherche, 0, strpos($recherche, "/"))));
            $searchField = "displayNamePrintable";
        } else {
            $searchField = "displayNamePrintable";
        }
        $result = $ldap->search("(&(objectclass=*)($searchField=$recherche))", $this->get_dn(), Zend_Ldap::SEARCH_SCOPE_SUB, $this->_remonter);
        $utilisateurs = array();
        foreach ($result as $item) {
            $utilisateurs[] = $item;
        }
        return $utilisateurs;
    }

    /**
     *
     * @param $_mdp the
     *            $_mdp to set
     */
    public function set_mdp( $_mdp )
    {
        $this->_mdp = $_mdp;
    }

    /**
     *
     * @param $_utilisateur the
     *            $_utilisateur to set
     */
    public function set_utilisateur( $_utilisateur )
    {
        $this->_utilisateur = $_utilisateur;
    }

    /**
     *
     * @param $_dn the
     *            $_dn to set
     */
    public function set_dn( $_dn )
    {
        $this->_dn = $_dn;
    }

    /**
     *
     * @param $_racineDn the
     *            $_racineDn to set
     */
    public function set_racineDn( $_racineDn )
    {
        $this->_racineDn = $_racineDn;
    }

    /**
     *
     * @param $_type the
     *            $_type to set
     */
    public function set_type( $_type )
    {
        $this->_type = $_type;
    }

    /**
     *
     * @param $_domaine the
     *            $_domaine to set
     */
    public function set_domaine( $_domaine )
    {
        $this->_domaine = $_domaine;
    }

    /**
     *
     * @param $_port the
     *            $_port to set
     */
    public function set_port( $_port )
    {
        $this->_port = $_port;
    }

    /**
     *
     * @return the $_mdp
     */
    public function get_mdp()
    {
        return $this->_mdp;
    }

    /**
     *
     * @return the $_utilisateur
     */
    public function get_utilisateur()
    {
        return $this->_utilisateur;
    }

    /**
     *
     * @return the $_dn
     */
    public function get_dn()
    {
        return $this->_dn;
    }

    /**
     *
     * @return the $_racineDn
     */
    public function get_racineDn()
    {
        return $this->_racineDn;
    }

    /**
     *
     * @return the $_type
     */
    public function get_type()
    {
        return $this->_type;
    }

    /**
     *
     * @return the $_domaine
     */
    public function get_domaine()
    {
        return $this->_domaine;
    }

    /**
     *
     * @return the $_port
     */
    public function get_port()
    {
        return $this->_port;
    }

    /**
     *
     * @param $_hostname the
     *            $_hostname to set
     */
    public function set_hostname( $_hostname )
    {
        $this->_hostname = $_hostname;
    }

    /**
     *
     * @return the $_hostname
     */
    public function get_hostname()
    {
        return $this->_hostname;
    }

    /**
     *
     * @param $_donneesLdap the
     *            $_donneesLdap to set
     */
    public function set_donneesLdap( $_donneesLdap )
    {
        $this->_donneesLdap = $_donneesLdap;
    }

    /**
     *
     * @return the $_donneesLdap
     */
    public function get_donneesLdap()
    {
        return $this->_donneesLdap;
    }

    public function recupAttributLdap( $attribut = "" )
    {
        if (is_array($this->_donneesLdap) && array_key_exists($attribut, $this->_donneesLdap) && is_array($this->_donneesLdap[$attribut])) {
            if (count($this->_donneesLdap[$attribut]) > 1) {
                return $this->_donneesLdap[$attribut];
            } else {
                return $this->_donneesLdap[$attribut][0];
            }
        } elseif ($attribut == "dn") {
            return $this->_donneesLdap[$attribut];
        }
        return "";
    }

    public function sauvegarder( $membres )
    {
        $ldap = $this->_ldap;
        try {
            $ldap->update($this->recupAttributLdap("distinguishedname"), $membres);
        }
        catch (Exception $e) {
            throw new Zend_Ldap_Exception($e->getMessage());
        }
    }

    public function desactiver()
    {
        $ldap = $this->_ldap;
        try {
            $ldap->update($this->recupAttributLdap("distinguishedname"), array(
                "useraccountcontrol" => 2, 
                "pager" => "", 
                "ddbaccessbadge" => ""
            ));
        }
        catch (Exception $e) {
            throw new Zend_Ldap_Exception();
        }
    }

    private function chargeCompte( $fldap )
    {
        $result = null;
        $f = @fopen($fldap, 'r');
        if ($f) {
            $stat = fstat($f);
            $result = unserialize(fread($f, $stat['size']));
            fclose($f);
        } else {
            throw new Exception(__("l'accès au fichier $fldap est impossible."));
        }
        return $result;
    }

    private function sauveCompte( $fldap, $user )
    {
        $f = @fopen($fldap, 'w');
        if ($f) {
            $data = serialize($user);
            fwrite($f, $data, strlen($data));
            fclose($f);
        } else {
            throw new Exception(__("l'enregistrement du fichier $fldap est impossible."));
        }
    }

    public function getUserDn()
    {
        return $this->recupAttributLdap("distinguishedname");
    }

    public function getUsernameNice()
    {
        return $this->recupAttributLdap("cn") . "/" . $this->recupAttributLdap("company");
    }

    /**
     * Fonction permettant de retourner la dernière OU pour le dn données
     *
     * @param $dn string           
     */
    public static function get_Societe_Ou( $dn )
    {
        $sep = ",OU=";
        $position = strpos($dn, $sep);
        $tmp = substr($dn, strlen($sep) + $position);
        $tmp = explode(",", $tmp);
        return $tmp[0];
    }
}